package com.libra.assemble.web.controller.authority;

import com.google.common.collect.Maps;
import com.libra.assemble.entity.authority.Role;
import com.libra.assemble.entity.authority.User;
import com.libra.assemble.service.authority.RoleService;
import com.libra.assemble.service.authority.UserService;
import com.libra.assemble.web.form.ActionMessageForm;
import com.libra.assemble.xutil.Constants;
import com.libra.assemble.xutil.Utils;
import com.libra.assemble.xutil.web.Servlets;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.ServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 用户信息管理的业务代理.
 *
 * @author Libra
 */
@Controller
@RequestMapping(value = "/user")
public class UserController {

    /**
     * 用户管理的业务逻辑
     */
    @Autowired
    private UserService userService;

    /**
     * 角色管理的业务处理
     */
    @Autowired
    private RoleService roleService;

    /**
     * 用户列表.
     *
     * @param pageNumber
     * @param pageSize
     * @param model
     * @param request
     * @return
     */
    @RequestMapping(method = RequestMethod.GET)
    public String list(@RequestParam(value = "page", defaultValue = "1") int pageNumber,
                       @RequestParam(value = "page.size", defaultValue = Constants.PAGE_SIZE_10) int pageSize,
                       Model model, ServletRequest request) {
        Map<String, Object> searchParams = Servlets.getParametersStartingWith(request, "search_");
        Page<User> users = userService.getUser(searchParams, pageNumber, pageSize);

        model.addAttribute("users", users);
        // 将搜索条件编码成字符串，用于排序，分页的URL
        model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, "search_"));

        return "authority/user-list";
    }

    /**
     * 进入用户创建页面.
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.GET)
    public String create(Model model) {
        User user = new User();
        List<Role> allRole = roleService.getAllRole();
        model.addAttribute("user", user);
        model.addAttribute("allRole", allRole);
        model.addAttribute("isExist", isExist(allRole, new ArrayList<Role>()));
        model.addAttribute("action", "create");
        return "authority/user-form";
    }

    /**
     * 创建用户.
     *
     * @param newUser
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "create", method = RequestMethod.POST)
    public String create(@Valid User newUser, @RequestParam(value = "roles.id") List<Long> rolesIds, RedirectAttributes redirectAttributes) {
        newUser.setRoles(new ArrayList<Role>());
        for (Long rolesId : rolesIds) {
            newUser.getRoles().add(roleService.getRole(rolesId));
        }
        newUser.setCreateTime(new Date());
        userService.registerUser(newUser);
        redirectAttributes.addFlashAttribute("message", new ActionMessageForm("success", "很好", "用户［" + newUser.getName() + "］添加成功。"));
        return "redirect:/user";
    }


    /**
     * 进入用户更新页面.
     *
     * @param id
     * @param model
     * @return
     */
    @RequestMapping(value = "update/{id}", method = RequestMethod.GET)
    public String update(@PathVariable("id") Long id, Model model) {
        User user = userService.getUser(id);
        List<Role> allRole = roleService.getAllRole();
        model.addAttribute("user", user);
        model.addAttribute("allRole", allRole);
        model.addAttribute("isExist", isExist(allRole, user.getRoles()));
        model.addAttribute("action", "update");
        return "authority/user-form";
    }

    /**
     * 提交更新的用户信息.
     *
     * @param user
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "update", method = RequestMethod.POST)
    public String update(@Valid @ModelAttribute("user") User user, @RequestParam(value = "roles.id") List<Long> rolesIds, RedirectAttributes redirectAttributes) {
        user.setRoles(new ArrayList<Role>());
        for (Long rolesId : rolesIds) {
            user.getRoles().add(roleService.getRole(rolesId));
        }
        userService.updateUser(user);
        redirectAttributes.addFlashAttribute("message", new ActionMessageForm("success", "很好！", "用户［" + user.getName() + "］已成功更新。"));
        return "redirect:/user";
    }

    /**
     * 用户密码修改.
     *
     * @return
     */
    @RequestMapping(value = "updatePassword", method = RequestMethod.POST)
    @ResponseBody
    public String updatePassword(@RequestParam(value = "oldPassword") String oldPassword,
                                 @RequestParam(value = "newPassword") String newPassword,
                                 @RequestParam(value = "confirmPassword") String confirmPassword) {

        if (Utils.isBlank(newPassword) || Utils.isBlank(confirmPassword)) {
            return "{\"status\":false,\"message\":\"密码不能为空，请输入密码！\"}";
        }

        if (!newPassword.equals(confirmPassword)) {
            return "{\"status\":false,\"message\":\"您两次输入的新密码不一致，请确认！\"}";
        }

        User user = userService.getUser(Utils.getCurrentUserId());
        if (!user.getPassword().equals(userService.entryptPassword(user.getSalt(), oldPassword))) {
            return "{\"status\":false,\"message\":\"请输入正确的当前密码！\"}";
        }

        user.setPlainPassword(newPassword);
        userService.updateUser(user);

        return "{\"status\":true,\"message\":\"您的密码修改成功，请重新登录！\"}";
    }

    /**
     * 删除用户记录.
     *
     * @param id
     * @param redirectAttributes
     * @return
     */
    @RequestMapping(value = "delete/{id}")
    public String delete(@PathVariable("id") Long id, RedirectAttributes redirectAttributes) {
        userService.deleteUser(id);
        redirectAttributes.addFlashAttribute("message", new ActionMessageForm("warning", "注意：", "用户已被成功删除！"));
        return "redirect:/user";
    }

    /**
     * 所有RequestMapping方法调用前的Model准备方法, 实现预处理部分绑定的效果,先根据form的id从数据库查出User对象,再把Form提交的内容绑定到该对象上。
     * 因为仅update()方法的form中有id属性，因此仅在update时实际执行.
     */
    @ModelAttribute
    public void getUser(@RequestParam(value = "id", defaultValue = "-1") Long id, Model model) {
        if (id != -1) {
            model.addAttribute("user", userService.getUser(id));
        }
    }

    /**
     * 判断用户是否有该角色权限.
     *
     * @param allRole
     * @param userRole
     * @return
     */
    private Map<Long, Boolean> isExist(List<Role> allRole, List<Role> userRole) {
        Map<Long, Boolean> map = Maps.newHashMap();

        for (Role role : allRole) {
            if (userRole.contains(role)) {
                map.put(role.getId(), true);
            } else {
                map.put(role.getId(), false);
            }
        }

        return map;
    }
}
